//
//
// based on a Simple HTTP server sample for sanos
//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <Ws2tcpip.h>

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <dirent.h>

#include <errno.h>


#define PORT "40505"
#define MY_PACKET_SIZE 510
#define SEND_TIMEOUT 5000  //in milliseconds


//
// Send len bytes out
//
int sendb(SOCKET *s, char *buf, int len)
{ int iSendResult,iResult;

  iResult=len;
  if (buf[len]!=0) buf[len]=0;
//  printf("Sending....");
  iSendResult = send(*s, buf, iResult, 0);
//  printf("Sent %d %d\n",iSendResult, iResult);
  if (iSendResult == SOCKET_ERROR) 
    {
       printf("send failed: %d\n", WSAGetLastError());
       closesocket(*s);
       WSACleanup();
       return 1;
    }
    return 0;
}
//
// Send a string
//
int sends(SOCKET *s, char *buf) { return sendb(s,buf,strlen(buf)); }


//
// Send the contents of a file
//
void send_file(SOCKET *s, char *path, struct stat *statbuf)
{
  char data[MY_PACKET_SIZE+1];
  int n,i;

  FILE *file = fopen(path, "r");

    int length = S_ISREG(statbuf->st_mode) ? statbuf->st_size : -1;
    printf("Sending File %s size %d\n",path,length);
//    while ((n = fread(data, sizeof(char), MY_PACKET_SIZE, file)) > 0) 
    for (i=0; i<MY_PACKET_SIZE; i++) data[i]=0;
    while (fgets(data,MY_PACKET_SIZE,file))
     { 
//          data[n]=0; 
          for (i=0; i<MY_PACKET_SIZE; i++) 
            { if (data[i]==10) data[i]=0;
              if (data[i]==92) data[i]=10; }
          n=strlen(data);
          printf("Sending %d bytes-%s\n",n,data);
          if ((i=sendb(s,data,n))==1) break; // exit if failed to send
//          printf("Sent\n");
          Sleep(1000);
          for (i=0; i<MY_PACKET_SIZE; i++) data[i]=0;
     }
}


//
// Process the current request
//
int process(SOCKET *s)
{
  char buf[4096];
  char path[256], *bitpath;
  struct stat statbuf;
  int len;
  char line[4096];

  Sleep(10000);                              // wait 10 secs before snding
  send_file(s, "Emulate7mc.txt", &statbuf);  // then send the file

  return 0;
}


//
// Main entry point
//
int main(int argc, char *argv[])
{
  int iResult,sock;
  WSADATA wsaData;
  struct addrinfo *result = NULL, *ptr = NULL, hints;
  SOCKET ListenSocket = INVALID_SOCKET;
  DWORD packet_timeout=SEND_TIMEOUT;
  struct sockaddr_in client;
  int client_size;


    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) { printf("WSAStartup failed: %d\n", iResult); return 1; }

    ZeroMemory(&hints, sizeof (hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;


    // Resolve the local address and port to be used by the server
    iResult = getaddrinfo("0.0.0.0", PORT, &hints, &result);
    if (iResult != 0) { printf("getaddrinfo failed: %d\n", iResult); WSACleanup(); return 1; }

    // Create a SOCKET for the server to listen for client connections
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) 
      {
       printf("Error at socket(): %ld\n", WSAGetLastError());
       freeaddrinfo(result);
       WSACleanup();
       return 1;
      }
 
    iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR) 
      { 
        printf("bind failed with error: %d\n", WSAGetLastError());
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
      }
    freeaddrinfo(result);

    if ( listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR ) 
      {
        printf( "Listen failed with error: %ld\n", WSAGetLastError() );
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
      }

    while (1)
    {
      SOCKET s;
      FILE *f;

      s = INVALID_SOCKET;

      printf("==========================================================\n");
      // Accept a client socket
      client_size=sizeof(client);
      s = accept(ListenSocket,(struct sockaddr *)&client,&client_size);
      if (s == INVALID_SOCKET) 
        {
         printf("accept failed: %d\n", WSAGetLastError());
         closesocket(ListenSocket);
         WSACleanup();
         return 1;
        }
      printf("Got a client\n");

      if ((iResult=setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,(char *)&packet_timeout,sizeof(packet_timeout)))==SOCKET_ERROR)
      { 
        printf("setsockopt send timeout Failed with Error: %d\n", WSAGetLastError());
        closesocket(s);
        WSACleanup();
        return 1;
      }

      if ((iResult=setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char *)&packet_timeout,sizeof(packet_timeout)))==SOCKET_ERROR)
      { 
        printf("setsockopt recv timeout Failed with Error: %d\n", WSAGetLastError());
        closesocket(s);
        WSACleanup();
        return 1;
      }
      printf("----------------------------------------------------------\n");
      process(&s);
      printf("----------------------------------------------------------\n");
      closesocket(s);
    }

  closesocket(ListenSocket);
  WSACleanup();
  return 0;
}
